package com.zhihuishu.micro.course.service;

import com.zhihuishu.micro.course.dto.SortableDto;
import com.zhihuishu.micro.course.dto.TreenityDto;
import com.zhihuishu.micro.course.service.impl.BaseTreenityServiceImpl;

import java.util.List;


/**
 * 增删改查通用接口
 * 注意：
 * DTO实际需要实现以下方法
 *
 * {@link SortableDto#getRank()}
 * {@link TreenityDto#getId()}
 * {@link TreenityDto#getOneToManyId()}
 *
 * 有了getRank方法，注定了dto列表可以排序
 * {@link BaseTreenityServiceImpl#getDtoListSorter}默认使用了getRank方法排序
 * 子类也可以重写方法并返回null，代表不支持排序，此时无视getRank返回值
 * @since branch:req-treenity-3
 *
 * getOneToManyId方法意味着
 * 1.数据库对象必然存有某个字段字段，且该字段对应的对象与该对象为一对多关系
 * 1.且缓存的id-set(dto id set)是以getOneToManyId生成key的
 * 其它情况该接口不适用。
 * 此外，一对多的缓存关系key的生成将依赖该方法,
 * @see TreenityRedisService#getIdsKey
 *
 * --------------------------------------------------------------------
 *
 * 该接口实际上只是做控制中转，用来控制执行下列方法的执行顺序以及执行或否
 * 实际存储发生在下列接口实现当中
 * @see TreenityDBService
 * @see TreenityRedisService
 *
 * 该接口的公共实现类是
 * @see BaseTreenityServiceImpl
 * 完成了通用的控制中转，子类可以重写中转逻辑以满足业务需要
 *
 * @author jiangli
 * @since branch req-treenity-2
 */
public interface TreenityService<DTO extends TreenityDto> {

    /**
     * 增
     * db决定了在redis中的初始数据字段
     */
	Integer create(DTO dto, long creator);

    /**
     * 查-dto list
     * dependency:
     * @see #listDtoIds(long)
     * @see #list(List)
     */
	List<DTO> list(long oneToManyId);

    /**
     * 查-dto detail
     * db返回的detail决定了dto在redis中的数据字段
     *
     * detail一定要返回oneToManyId
     */
    DTO detail(Integer dtoId);

    /**
     * 查-id list
     */
    List<Integer> listDtoIds(long oneToManyId);

    /**
     * 查-dto list
     */
    List<DTO> list(List<Integer> dtoIdList);

    /**
     * 改
     */
    void update(DTO dto, long updateUserId);

    /**
     * 删
     * dependency:
     * @see #detail(Integer)
     */
    void delete(Integer dtoId, long deleteUserId);


}
